#ifndef NANE_DESERIALIZATIONPROTOCOL_H
#   define  NANE_DESERIALIZATIONPROTOCOL_H

#   include "nane/SerializeSystem/ISerializeSystem.h"
#   include "nane/SerializeSystem/DeserializationTypeProtocol.h"
#   include "nane/SerializeSystem/DeserializationFunctionProtocol.h"
#   include "nane/core/function/Functor.h"

#   include <vector>

namespace nane
{
    template<bool StrictOrder = false>
    class DeserializationProtocol
        : public ISerializationProtocol
    {
    public:
        DeserializationProtocol();
        ~DeserializationProtocol();

        template<typename TValue>
        void Deserialize( const char* _tag, TValue* _value )
        {
            m_handlers.push_back( new DeserializationTypeProtocol<TValue>(_tag, _value) );
        }

        template<typename F>
        void DeserializeFunction( const char* _tag, F _function )
        {
            m_handlers.push_back(FunctorAdapter_(_tag, MakeFunctor(_function)));
        }

        template<typename F>
        void DeserializeFunctor( const char* _tag, F _functor )
        {
            m_handlers.push_back(FunctorAdapter_(_tag, _functor));
        }

        template<class C, typename F>
        void DeserializeMemberFunction( const char* _tag, F _function, C* _object )
        {
            m_handlers.push_back(FunctorAdapter_(_tag, MakeMemberFunctor(_function, _object)));
        }

    private:
        template<typename F>
        DeserializationTypeBase* FunctorAdapter_( const char* _tag, F _functor )
        {
            return new DeserializationFunctionProtocol<F, typename F::TParam1>(_tag, _functor);
        }

        template<typename T>
        bool SerializeImpl_( const char* _tag, T _data );

    protected:
        bool Serialize( const char* _tag );
        bool Serialize( const char* _tag, int32 _data );
        bool Serialize( const char* _tag, uint32 _data );
        bool Serialize( const char* _tag, float _data );
        bool Serialize( const char* _tag, bool _data );
        bool Serialize( const char* _tag, const char* _data );

    private:
        std::vector<DeserializationTypeBase*> m_handlers;
    };

    typedef DeserializationProtocol<true> DeserializationProtocolStrict;
}   // namespace nane

#endif	// NANE_DESERIALIZATIONPROTOCOL_H
